﻿#ifndef tk_data_type_hpp
#define tk_data_type_hpp

#include "tk_define.h"
#include <QRgb>
//#include <boost/integer.hpp>
//#include <climits>

//===========================================================
typedef qint8          tk_int8,         *tk_pint8;
typedef quint8         tk_uint8,	*tk_puint8;
typedef qint16         tk_int16,	*tk_pint16;
typedef quint16        tk_uint16,       *tk_puint16;
typedef qint32         tk_int32,	*tk_pint32;
typedef quint32        tk_uint32,       *tk_puint32;
typedef qint64         tk_int64,	*tk_pint64;
typedef quint64        tk_uint64,       *tk_puint64;

#define TK_INT8_MIN     INT8_MIN
#define TK_INT8_MAX     INT8_MAX

#define TK_UINT8_MIN	0
#define TK_UINT8_MAX	UINT8_MAX

#define TK_INT16_MIN	INT16_MIN
#define TK_INT16_MAX	INT16_MAX

#define TK_UINT16_MIN	0
#define TK_UINT16_MAX	UINT16_MAX

#define TK_INT32_MIN	INT32_MIN
#define TK_INT32_MAX	INT32_MAX

#define TK_UINT32_MIN	0
#define TK_UINT32_MAX	UINT32_MAX

#define TK_INT64_MIN	INT64_MIN
#define TK_INT64_MAX	INT64_MAX

#define TK_UINT64_MIN	0
#define TK_UINT64_MAX	UINT64_MAX

typedef size_t		tk_size_t, *tk_psize_t;
#define TK_SIZE_MIN     0
#define TK_SIZE_MAX     SIZE_MAX

//===========================================================
typedef char			tk_char, tk_byte, *tk_pchar, *tk_pbyte;
typedef unsigned char   tk_uchar, *tk_puchar;
#define TK_CHAR_MIN 	CHAR_MIN
#define TK_CHAR_MAX     CHAR_MAX
#define TK_UCHAR_MIN	0
#define TK_UCHAR_MAX	UCHAR_MAX

typedef wchar_t			tk_wchar, *tk_pwchar;
#define TK_WCHAR_MIN	WCHAR_MIN
#define TK_WCHAR_MAX	WCHAR_MAX

//===========================================================
typedef bool		tk_bool,	*tk_pbool;
#define TK_TRUE		true
#define TK_FALSE	false

//===========================================================
typedef float		tk_float,	*tk_pfloat;
#define TK_FLOAT_MIN	FLT_MIN
#define TK_FLOAT_MAX	FLT_MAX

typedef double		tk_double, *tk_pdouble;
#define TK_DOUBLE_MIN	DBL_MIN
#define TK_DOUBLE_MAX	DBL_MAX

//===========================================================
typedef void*		tk_pointer;

#define	TK_NULL         0
#define	TK_NULL_PTR     nullptr

typedef QRgb		tk_rgb,		*tk_prgb;
#define TK_RGB(r,g,b)			qRgb(r,g,b)
#define TK_RGB_MIX(a,b,alpha)	(tk_uint8((1-alpha)*b+alpha*a))
#define TK_RGB_R(rgb)			qRed(rgb)
#define TK_RGB_G(rgb)			qGreen(rgb)
#define TK_RGB_B(rgb)			qBlue(rgb)



#ifdef __cplusplus
extern "C++"
{
	template <typename T, tk_size_t N>
	inline	tk_size_t tk_count_of(const T(&)[N]){return N;}
}
#else
#	define tk_count_of( a ) \(sizeof( a ) / sizeof( a[ 0 ] ))
#endif

//=======================================================================
#define SAFE_DELETE(p)       { if(p) { delete (p);     (p)=TK_NULL_PTR; } }
#define SAFE_DELETE_ARRAY(p) { if(p) { delete[] (p);   (p)=TK_NULL_PTR; } }

//=======================================================================
template <typename T>
struct tk_point
{
    T x;
    T y;

	tk_point() :x(0), y(0) {}
	tk_point(T _x, T _y) :x(_x), y(_y) {}
};

//=======================================================================
template<typename T>
struct tk_rect{
	T left;
	T top;
	T right;
	T bottom;
	tk_rect():
	left(0),top(0),right(0),bottom(0)
	{

	}
};

template<typename T>
void tk_set_rect(tk_rect<T> *prect,T left,T top,T right,T bottom)
{
	prect->left = left;
	prect->top = top;
	prect->right = right;
	prect->bottom = bottom;
}
template<typename T>
void tk_set_rect(tk_rect<T> &rect, T left, T top, T right, T bottom)
{
	rect.left = left;
	rect.top = top;
	rect.right = right;
	rect.bottom = bottom;
}
template<typename T>
T tk_rect_width(tk_rect<T> &rect)
{
	return rect.right-rect.left;
}

template<typename T>
T tk_rect_height(tk_rect<T> &rect)
{
	return rect.bottom-rect.top;
}

template<typename T>
T tk_rect_space(tk_rect<T> &rect)
{
	return tk_rect_width(rect)*tk_rect_height(rect);
}

template<typename T>
bool tk_rect_size_cmp(tk_rect<T> &rect_scr1,tk_rect<T> &rect_scr2)
{
	return (
		tk_rect_width(rect_scr1)== tk_rect_width(rect_scr2) && 
		tk_rect_height(rect_scr1)== tk_rect_height(rect_scr2)
		);
}

template<typename T>
bool tk_rect_size_equal(tk_rect<T> &rect_scr1,tk_rect<T> &rect_scr2)
{
	return (
		rect_scr1.left  == rect_scr2.left		&&
		rect_scr1.right  == rect_scr2.right		&&
		rect_scr1.top  == rect_scr2.top			&&
		rect_scr1.bottom  == rect_scr2.bottom
		);
}

template<typename T>
void tk_rect_max(tk_rect<T> &rect_max, tk_rect<T> &rect_scr1,tk_rect<T> &rect_scr2)
{
	rect_max.left = min(rect_scr1.left,rect_scr2.left);
	rect_max.right = max(rect_scr1.right,rect_scr2.right);
	rect_max.top = min(rect_scr1.top,rect_scr2.top);
	rect_max.bottom = max(rect_scr1.bottom,rect_scr2.bottom);
}
//=======================================================================

template<typename T>
struct tk_quad_pts
{
	tk_point<T> left_top;
	tk_point<T> left_bottom;
	tk_point<T> right_top;
	tk_point<T> right_bottom;
};

#endif // tk_data_type_hpp
